package com.dbsop.mapper;

import com.dbsop.EsClient;
import com.dbsop.domain.*;
import com.dbsop.domain.params.*;
import com.dbsop.exception.EsRunException;
import com.dbsop.request.ClientOpt;
import com.dbsop.request.ClientRequest;
import com.dbsop.wrapper.DataWrapper;

import java.io.Serializable;
import java.util.List;

public abstract class ESBaseMapper<T,ID extends Serializable> implements IndicesDoc<T> {

    protected IndexMappingInfo<T,ID> infoMapping;

    protected ClientOpt clientOpt;

    protected ClientRequest cq;

    public void init(){
        infoMapping= new IndexMappingInfo(this);
        clientOpt = EsClient.getEsClient().getClientOpt();
        cq =  clientOpt.getClientRequest();
    }


    /**
     * 保存数据
     * @param t
     * @return
     */
    public int save(T t){
        return cq.save(new SaveParams<T>(infoMapping,t));
    }

    /**
     * 批量保存
     * @param t
     * @return
     */
    public int saveBatch(List<T> t){
        return cq.saveBatch(new SaveParams<T>(infoMapping,t));
    }

    /**
     * 保存不为空的数据 此方法 T 必须存在主键ID
     * @return
     */
    public int saveNotNull(T t){
        return cq.saveBatch(new SaveParams<T>(infoMapping,t,true));
    }

    /**
     * 批量保存不为空的数据 此方法 T 必须存在主键ID
     * @param ts
     * @return
     */
    public int saveBatchNotNull(List<T> ts){
        return cq.saveBatch(new SaveParams<T>(infoMapping,ts,true));
    }


    /**
     * 根据条件修改字段值
     * @return
     */
    public int updateByQuery(EsUpdateCondition esUpdateCondition){
        return cq.updateByQuery(new ModifyParams(infoMapping,esUpdateCondition));
    }

    /**
     * 根据ID 查询数据
     * @param id
     * @return
     */
    public T selectById(ID id){
        EsCondition esCondition = EsCondition.getEsCondition().eq(infoMapping.getIdName(), id);
        List<T> ts = cq.selectList(new RequestParams<T>(esCondition, infoMapping.getEntity(), infoMapping));
        if (ts == null){
            return null;
        }
        if (ts.size()>1){
            throw new EsRunException(" By Id not a values ");
        }
        return ts.get(0);
    }


    /**
     * 根据ID 查询数据
     * @param id
     * @return
     */
    public T selectById(String index,ID id){
        EsCondition esCondition = EsCondition.getEsCondition();
        esCondition.addIndex(index);
        esCondition.eq(infoMapping.getIdName(),id).size(10);
        List<T> ts = selectList(esCondition);
        if (ts.size() >1){
            throw new RuntimeException("");
        }
        if (ts.size() == 1){
            return ts.get(0);
        }
        return null;
    }

    /**
     * 根据条件查询
     * @param esCondition
     * @return
     */
    public List<T> selectList( EsCondition esCondition){
        return cq.selectList(new RequestParams<T>(esCondition, infoMapping.getEntity(), infoMapping));
    }

    /**
     * 根据条件查询 指定返回类型
     * @param esCondition
     * @param tClass
     * @param <E>
     * @return
     */
    public <E> List<E> selectList(EsCondition esCondition, Class<E> tClass){
        return cq.selectList(new RequestParams<E>(esCondition, tClass, infoMapping));
    }


    /**
     * 根据条件查询 自处理返回类型
     * @param esCondition
     * @param dataWrapper
     * @return
     */
    public <E> List<E> selectList(EsCondition esCondition, DataWrapper<E> dataWrapper){
        return cq.selectList(new RequestParams<E>(esCondition,  infoMapping,dataWrapper));
    }

    /**
     * 根据某个字段进行折叠然后进行 数据排名
     * @param esCondition
     * @param <E>
     * @return
     */
    public <E> List<E> collapseList(EsCondition esCondition, Class<E> clazz){
        return cq.collapseList(new CollapseParams<E>(esCondition,clazz,infoMapping));
    }

    /**
     * 根据某个字段进行折叠然后进行 数据排名
     * @param esCondition
     * @param dataWrapper
     * @param <E>
     * @return
     */
    public <E> List<E> collapseList(EsCondition esCondition, DataWrapper<E> dataWrapper){
        return cq.collapseList(new CollapseParams<E>(esCondition,infoMapping,dataWrapper));
    }

    /**
     * 分页
     * 根据条件查询 自处理返回类型
     * @param esCondition
     * @param dataWrapper
     * @return
     */
    public <E> ESPage<E> selectPageList(EsCondition esCondition, int currentNumber, int  currentSize,
                                                 DataWrapper<E> dataWrapper){
        return cq.selectPageList(new PageParams<E>(esCondition,infoMapping,new ESPage(currentNumber,currentSize),dataWrapper));
    }


    /**
     * 分页
     * 根据条件查询
     * @param esCondition
     * @return
     */
    public ESPage<T> selectPageList(EsCondition esCondition, int currentNumber, int  currentSize){
        return cq.selectPageList(new PageParams<T>(esCondition,infoMapping.getEntity(),infoMapping,
                new ESPage(currentNumber,currentSize)));
    }

    /**
     * 分页
     * 根据条件查询 指定返回类型
     * @param esCondition
     * @param tClass
     * @param <E>
     * @return
     */
    public <E> ESPage<E> selectPageList(EsCondition esCondition, int currentNumber, int  currentSize, Class<E> tClass){
        return cq.selectPageList(new PageParams<E>(esCondition,tClass,infoMapping,
                new ESPage(currentNumber,currentSize)));
    }
//
//
//
//
//
//
//    /**
//     * 根据条件查询所有結果集
//     * @param esCondition
//     * @return
//     */
//    public abstract List<T> selectListBatch(EsCondition esCondition);
//
//    /**
//     * 根据条件查询 指定返回类型
//     * @param esCondition
//     * @param tClass
//     * @param <E>
//     * @return
//     */
//    public abstract <E> List<E> selectListBatch(EsCondition esCondition, Class<E> tClass);
//
//
//    /**
//     * 根据条件查询 自处理返回类型
//     * @param esCondition
//     * @param dataWrapper
//     * @return
//     */
//    public abstract <E> List<E> selectListBatch(EsCondition esCondition, DataWrapper<E> dataWrapper);


    /**
     * 聚合操作
     * 根据条件查询 指定返回类型
     * @param esAggCondition
     * @param resClass
     * @param <E>
     * @return
     */
    public <E> List<E> selectListAgg(EsAggCondition esAggCondition, Class<E> resClass){
        return cq.selectListAgg(new AggRequestParams<E>(esAggCondition,resClass,infoMapping));
    }


    /**
     * 聚合操作
     * 根据条件查询 指定返回类型
     * @param esAggCondition
     * @param <E>
     * @return
     */
    public <E> List<E> selectListAgg(EsAggCondition esAggCondition, DataWrapper<E> dataWrapper){
        return cq.selectListAgg(new AggRequestParams<E>(esAggCondition,infoMapping,dataWrapper));
    }


    /**
     * 删除操作
     * @param id
     * @return
     */
    public int deleteById(ID id){
        EsCondition esCondition = EsCondition.getEsCondition().eq(infoMapping.getIdName(), id);
        return cq.deleteBySearch(new DeleteParams(infoMapping, esCondition));
    }

    /**
     * 根据所选条件进行删除
     * @param esCondition
     * @return
     */
    public int deleteBySearch(EsCondition esCondition){
        return cq.deleteBySearch(new DeleteParams(infoMapping, esCondition));
    }
}
